ItIron2021
Javascript
昨天我們探討了undefined、null & not defined的基本差異,今天我們繼續透過其他的題目進一步了解變數型別相關的問題吧!
請問下方程式碼輸出結果為何
let bar = true;
console.log(bar + 0);
console.log(bar + 'xyz');
console.log(bar + true);
console.log(bar + false);
老樣子來張全新的防雷圖~思考完再往下捲動吧!
最終的輸出結果為
1
truexyz
2
1
這就是javascript中讓人又愛又恨的其中一個地方,強制轉型(coercion),簡單說就是在某些情況下(變數間的比較、運算子或是條件式等使用等),javascript會透過自己的一套方法將變數轉為它想要的型態再做處理,舉個常見的例子,你在實務中可能看過類似以下的程式碼
if (list.length) {
console.log('你的名單不是空的,真是太好了,你不是邊緣人呢!')
} else {
console.log('可憐的傢伙,連朋友都沒有,這個口香糖拿去吃吧!')
}
上述的程式碼就是一個善用強制轉型的典型例子,條件式內的expression會被強制轉為boolean值,藉由這樣可以少些一些程式碼! 不過當你不了解這類的轉型規則時,你很容易像今天的題目一樣慌了手腳。強制轉型是絕對有完整的規則的,有興趣的可以去探究一下背後的原理,MDN也有提供一張表格讓你知道在比較時是怎麼做轉型再比較的。
現在你知道規則是有的,我們再回頭看一下題目吧! 當變數間用+運算子處理時,便會觸發強制轉型,畢竟它必須先知道是要連接還是加總嘛!你當然可以深究其原理再處理這道題目,不過實際上我個人的經驗是這樣的
再次強調,背後是真的有一套規則在的,有興趣的自行探究,會關係到底層如何用valueOf去一個一個處理轉型,但有了以上的基本原則就足夠你應付多數的面試題目了,照以上的原則分析這次的問題吧!
console.log(true + 0); // 只有布林&數字,轉數字處理,1 + 0 = 1
console.log(true + 'xyz'); // 有字串,用字串連接處理,'true' + 'xyz' = 'truexyz'
console.log(true + true); // 只有布林,轉數字處理,1 + 1 = 1
console.log(true + false); // 只有布林,轉數字處理,1 + 0 = 1
當然,最好的辦法還是去好好了解底層是怎麼運作的,但以上原則面對jr的面試與實務已經完全足夠了,真的慌了手腳的話就猜都轉字串吧? 不過這邊要特別注意不同的資料型別轉字串的方法稍微有點不一樣,舉個例子來說
[] + {}
遇到這種讓你手足無措的,你知道要猜轉字串再連接,問題是....這兩玩意轉字串是什麼鬼阿!
轉字串會透過toString方法去做轉型,但掛在Array & Object下的toString卻不完全一樣,有興趣的朋友可以自行研究一下,總之Object的toString方法會給比較多資訊,以上方的例子來說,空陣列呼叫本身的toString方法會回傳空字串,而空物件呼叫本身的toString方法則會回傳[object Object],最終輸出結果為以下
[] + {} => '' + '[object Object]' => '[object Object]'
強制轉型(coercion)
本文章同步發布於個人部落格,有興趣的朋友也可以來逛逛~!
Hi~
關於*「一旦有字串,就都轉成字串處理」* 這句話,在以下情況:5 - "2" // 3
"HELLO" - 5 // NAN
在減法的情況下,字串會轉型成數字進行處理,可以參考:
https://hackmd.io/@ivaSrwTTSkC1jb66rpGfnQ/B1wsiGaBK#%E6%B8%9B%E6%B3%95
謝謝~
irissss感謝回饋!想不到這麼久以前的文章還有人看wwww 確實光看這句一旦有字串,就都轉成字串處理是漏洞百出的,不過當時在寫文章時就有一個前提當變數間用+運算子處理時
,在這個前提下就沒什麼大問題了。
js在不同的運算子間確實有時會觸發不同規則的強制轉型,會用+運算子舉例單純是因為它是最常見的面試問題,並沒有辦法當作一個通則適用於所有的運算子。